package cz.muni.fi.pa165.creatures.model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

/**
 * This class represents a weapon we use against the {@link CreatureType}.
 * 
 * @author xmiklos1
 */
@Entity
@Table(name = "WEAPON", uniqueConstraints = {
    @UniqueConstraint(columnNames = "NAME")
})
public class Weapon implements Serializable {

    /**
     * Id of the weapon.
     */
    private Long id;
    
    /**
     * Name of the weapon. Max length of the name is 255 
     * characters and can't be null.
     */
    private String name;
    
    /**
     * Range of the weapon in meters (if applicable).
     */
    private Integer range;
    
    /**
     * Number of bullets in one full loaded weapon (if applicable).
     */
    private Integer ammunition;
    
    /**
     * Effectivities of the weapon against some creature type.
     */
    private Set<CreatureTypeWeaponEffectivity> creatureTypeWeaponEffectivities 
            = new HashSet<CreatureTypeWeaponEffectivity>(0);

    /**
     * Default constructor
     */
    public Weapon() {
    }

    /**
     *
     * @param name name of the weapon
     */
    public Weapon(String name) {
        this.name = name;
    }

    /**
     *
     * @param name name of the weapon
     * @param creatureTypeWeaponEffectivities
     */
    public Weapon(String name, Set<CreatureTypeWeaponEffectivity> creatureTypeWeaponEffectivities) {
        this.name = name;
        this.creatureTypeWeaponEffectivities = creatureTypeWeaponEffectivities;
    }

    /**
     * Gets the id of the weapon.
     *
     * @return id id of the weapon
     */
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ID", nullable = false)
    public Long getId() {
        return this.id;
    }

    /**
     * Sets the id of the weapon
     *
     * @param id id of the weapon
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * Gets name of the weapon.
     *
     * @return name of the weapon
     */
    @Column(name = "NAME", nullable = false)
    public String getName() {
        return this.name;
    }

    /**
     * Sets name of the weapon.
     *
     * @param name name of the weapon
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get range of the weapon in meters.
     *
     * @return range of the weapon in meters
     */
    @Column(name = "RANGE")
    public Integer getRange() {
        return this.range;
    }

    /**
     * Sets range of the weapon in meters.
     *
     * @param range range of the weapon in meters
     */
    public void setRange(Integer range) {
        this.range = range;
    }

    /**
     * Gets number of bullets in one fully loaded weapon (if applicable)
     *
     * @return number of bullets in one fully loaded weapon (if applicable)
     */
    @Column(name = "AMMUNITION")
    public Integer getAmmunition() {
        return this.ammunition;
    }

    /**
     * Sets number of bullets in one fully loaded weapon (if applicable)
     *
     * @param ammo number of bullets in one fully loaded weapon (if applicable)
     */
    public void setAmmunition(Integer ammunition) {
        this.ammunition = ammunition;
    }

    /**
     * 
     * @return effectivities of the weapon against the creatures
     */
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.weapon", cascade = CascadeType.ALL)
    public Set<CreatureTypeWeaponEffectivity> getCreatureTypeWeaponEffectivities() {
        return this.creatureTypeWeaponEffectivities;
    }

    /**
     * @param creatureTypeWeaponEffectivities 
     */
    public void setCreatureTypeWeaponEffectivities(Set<CreatureTypeWeaponEffectivity> creatureTypeWeaponEffectivities) {
        this.creatureTypeWeaponEffectivities = creatureTypeWeaponEffectivities;
    }

    @Override
    public String toString() {
        return "Weapon{" + "id=" + id + ", name=" + name + ", range=" + range
                + ", ammunition=" + ammunition + ", creatureTypeWeaponEffectivities="
                + creatureTypeWeaponEffectivities + '}';
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Weapon other = (Weapon) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
            return false;
        }
        return true;
    }
}
